home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 145
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin
/
tools
/
sharp
/
sxwork3.lzh
/
サンプル実用編
/
小遣い帳
/
CSCELL.C
< prev
next >
Wrap
Text File
|
1994-03-10
|
24KB
|
841 lines
/******************************************************************************
* cscell.c: 表計算用パッケージ
******************************************************************************
* Workroom SX-68K Sample Program Copyright 1994 SHARP
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <event.h> /* イベントマンを利用するときに必要 */
#include <sxgraph.h> /* グラフ系マネージャを利用するときに必要 */
#include <text.h> /* テキストマンを利用するときに必要 */
#include <task.h> /* タスクマンを利用するときに必要 */
#include "cash.h" /* このプログラム固有のヘッダファイル */
/******************************************************************************
* openCell(): セルのワークを作成する
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* Window *winPtr ウィンドウポインタ
* 戻り値: BOOLEAN = TRUE: 作成成功
* = FALSE: 作成失敗
*/
BOOLEAN openCell(Mtx *mp, Window *winPtr, LPoint lpt, int wide, int height, int fsize)
{
int errCode;
static Rect rctext = { 0, 0, 12, 12 };
/* セルの表示位置を設定 */
mp->pos.x_y = lpt;
/* セルの大きさを設定 */
mp->cWide = wide;
mp->cHeight = height;
/* フォントサイズを設定 */
mp->fontSize = fsize;
/* セル編集関係のフラグを初期化 */
mp->mCell.x = 0;
mp->mCell.y = 0;
mp->eCell.x = 0;
mp->eCell.y = 0;
mp->focus = 0;
mp->tEdit = NULL;
mp->edit = FALSE;
errCode = TMNew2(&rctext, &rctext, &winPtr->graph, &mp->tEdit);
if (errCode < 0)
return FALSE;
TMHide(mp->tEdit);
(*mp->tEdit)->lenMax = 1;
(*mp->tEdit)->lineHeight = mp->fontSize * 2;
(*mp->tEdit)->editMode = 0; /* 編集モードを通常表示にする */
/* ファンクションキーアサインテーブルを設定する */
(*mp->tEdit)->funcCode = funcKeyTbl;
return TRUE;
}
/******************************************************************************
* closeCell(): セルを廃棄する
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* Window *winPtr ウィンドウポインタ
*/
void closeCell(Mtx *mp, Window *winPtr)
{
GMSetGraph(&winPtr->graph);
mp->edit = FALSE;
mp->eCell.x = 0;
mp->eCell.y = 0;
mp->focus = 0;
mp->cAttH = NULL;
mp->cTitle = NULL;
mp->cData = NULL;
if (mp->tEdit != NULL) {
TMCaret(mp->tEdit, 0);
TMDispose(mp->tEdit); /* テキストを廃棄する */
mp->tEdit = NULL;
}
addUpdate(winPtr, &mp->rcAll);
}
/******************************************************************************
* setCellData(): セルのデータ配列を設定
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
*/
void setCellData(Mtx *mp, CAtt *ha, char **data, char ***tBuff)
{
int i;
mp->cAttH = ha;
mp->cTitle = tBuff;
mp->cData = data;
/* 全体のレクタングルを求める */
mp->rcAll.l.l_t = 0;
mp->rcAll.d.right = 0;
for (i = 0; i < mp->cWide; i++)
mp->rcAll.d.right += (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
mp->rcAll.d.right += OUTFRM * 2;
mp->rcAll.d.bottom = (mp->fontSize * 2 + CELLMG * 2) * mp->cHeight + (mp->fontSize * 2 + CELLMG * 2 + 1) * 2 + OUTFRM * 2;
GMSlideRect(&mp->rcAll, mp->pos.x_y);
/* データセルまでのオフセット */
mp->offset.p.x = OUTFRM;
mp->offset.p.y = (mp->fontSize * 2 + CELLMG * 2) + 1 + OUTFRM;
}
/******************************************************************************
* drawCell(): セル全体の描画
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
*/
void drawCell(Mtx *mp)
{
int i, x, dx;
CPoint cpt;
Rect rc;
GMAPage(G_PAGE0 | G_PAGE1); /* アクセスページを0と1ページにする */
drawCellFrame(&mp->rcAll, 2, 0);
rc = mp->rcAll;
GMInsetRect(&rc, LONGWORD(OUTFRM - 1, OUTFRM - 1));
drawCellFrame(&rc, 2, 1);
/* y座標は固定 */
rc.d.top = mp->pos.p.y + OUTFRM;
rc.d.bottom = rc.d.top + mp->fontSize * 2 + CELLMG * 2;
/* タイトルバーを描画する */
x = 0;
for (i = 0; i < mp->cWide; i++) {
dx = (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
rc.d.left = mp->pos.p.x + OUTFRM;
rc.d.right = rc.d.left + dx;
GMSlideRect(&rc, x << 16);
/* タイトルフレームを描画 */
drawCellFrame(&rc, 2, 0);
/* タイトル文字列を影付きで描画 */
GMShadowStrZ(*(*mp->cTitle + i), LONGWORD(rc.d.left + CELLMG, rc.d.top + CELLMG));
x += dx;
}
/* データセルを描画 */
for (cpt.y = 0; cpt.y < mp->cHeight; cpt.y++)
for (cpt.x = 0; cpt.x < mp->cWide; cpt.x++)
drawCellOne(mp, &cpt);
/* 合計用入力欄を描画 */
x = 0;
cpt.y = mp->cHeight;
rc.d.top = mp->pos.p.y + mp->offset.p.y + mp->cHeight * (mp->fontSize * 2 + CELLMG * 2) + 1;
rc.d.bottom = rc.d.top + (mp->fontSize * 2 + CELLMG * 2);
for (i = 0; i < mp->cWide; i++) {
dx = (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
if ((mp->cAttH + i)->attrib == 0)
/* 数値の場合、合計金額を計算 */
totalCell(mp, i);
else {
/* 数値以外の場合描画のみ */
rc.d.left = mp->pos.p.x + OUTFRM;
rc.d.right = rc.d.left + dx;
GMSlideRect(&rc, x << 16);
/* セルのフレームを描画 */
drawCellFrame(&rc, (mp->cAttH + i)->attrib, 0);
cpt.x = i;
drawCellStr(mp, &rc, &cpt);
}
x += dx;
}
}
/******************************************************************************
* drawCellOne(): 1つのセルを描画
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* CPoint *pcpt セルの位置へのポインタ
*/
void drawCellOne(Mtx *mp, CPoint *pcpt)
{
int lastFC, lastBC;
Rect rc;
CAtt *pcatt;
lastFC = GMForeColor(G_BLACK);
lastBC = GMBackColor(G_LGRAY);
/* セルの大きさを求める */
rc.l.l_t = 0;
rc.d.right = (mp->cAttH + pcpt->x)->length * mp->fontSize + CELLMG * 2;
rc.d.bottom = mp->fontSize * 2 + CELLMG * 2;
/* セル位置にレクタングルを移動 */
GMSlideRect(&rc, cptToLpt(mp, pcpt));
/* セルのフレームを描画 */
pcatt = mp->cAttH + pcpt->x;
drawCellFrame(&rc, pcatt->attrib, 0);
drawCellStr(mp, &rc, pcpt);
GMForeColor(lastFC);
GMBackColor(lastBC);
}
/******************************************************************************
* drawCellStr(): セル内に文字列を描画
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* CPoint *pcpt セルの位置へのポインタ
*/
void drawCellStr(Mtx *mp, Rect *prc, CPoint *pcpt)
{
int lastFC, lastBC;
Point pt;
CAtt *pcatt;
char str[256], *ar;
lastFC = GMForeColor(G_BLACK);
lastBC = GMBackColor(G_LGRAY);
pt.p.x = prc->d.left + CELLMG;
pt.p.y = prc->d.top + CELLMG;
/* 格納データのポインタを取得 */
pcatt = mp->cAttH + pcpt->x;
ar = *(mp->cData + pcatt->array);
switch (pcatt->attrib) {
case 0: /* 数値 */
/* 数値文字列を右揃えで出力 */
GMBackColor(G_WHITE);
sprintf(str, "%*d\0", pcatt->length - 1, *((int *) ar + pcpt->y));
GMMove(pt.x_y);
GMDrawStrZ(str);
break;
case 1: /* 文字列 */
/* 文字列を左揃えで出力 */
GMBackColor(G_WHITE);
strcpy(str, ar + pcpt->y * pcatt->size);
GMMove(pt.x_y);
GMDrawStrZ(str);
break;
case 2: /* タイトル */
/* タイトル文字列を影付きで出力 */
GMBackColor(G_LGRAY);
GMShadowStrZ(*(*(mp->cTitle + 1) + pcpt->y), pt.x_y);
break;
}
GMForeColor(lastFC);
GMBackColor(lastBC);
}
/******************************************************************************
* drawCellFrame(): セルのフレームを描画
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* short kind フレームを作成するセルのデータの種類
* short mode フレームの状態
* = 0: 通常表示
* = 1: 選択状態
*/
void drawCellFrame(Rect *prc, short kind, short mode)
{
int lastFC, lastBC, lc, rc;
Point pt;
lastFC = GMForeColor(G_BLACK);
lastBC = GMBackColor(G_LGRAY);
switch (kind) {
case 0:
case 1:
GMForeColor(G_WHITE);
GMFillRect(prc);
GMForeColor(G_BLACK);
GMMove(LONGWORD(prc->d.right - 1, prc->d.top));
GMLine(LONGWORD(prc->d.right - 1, prc->d.bottom - 1));
GMMove(LONGWORD(prc->d.left, prc->d.bottom-1));
GMLine(LONGWORD(prc->d.right - 1, prc->d.bottom - 1));
break;
case 2:
if (mode == 1) { /* mode = 1なら、窪んだレクタングル */
lc = G_BLACK;
rc = G_WHITE;
} else { /* mode = 0なら、浮き出たレクタングル */
lc = G_WHITE;
rc = G_BLACK;
}
/* 光沢部分 */
lastFC = GMForeColor(lc);
pt.p.x = prc->d.left;
pt.p.y = prc->d.bottom - 1;
GMMove(pt.x_y);
pt.p.y = prc->d.top;
GMLine(pt.x_y);
pt.p.x = prc->d.right - 2;
GMLine(pt.x_y);
/* 光沢と影の境 */
GMForeColor(G_DGRAY);
pt.p.x++;
GMMove(pt.x_y);
GMLine(pt.x_y);
/* 影の部分 */
GMForeColor(rc);
pt.p.y++;
GMMove(pt.x_y);
pt.p.y = prc->d.bottom - 1;
GMLine(pt.x_y);
pt.p.x = prc->d.left + 1;
GMLine(pt.x_y);
/* 光沢と影の境 */
GMForeColor(G_DGRAY);
pt.p.x--;
GMMove(pt.x_y);
GMLine(pt.x_y);
}
GMForeColor(lastFC);
GMBackColor(lastBC);
}
/******************************************************************************
* cptToLpt(): セルの座標から物理座標を求める
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* CPoint *pcpt セルの位置へのポインタ
* 戻り値: LPoint
*/
LPoint cptToLpt(Mtx *mp, CPoint *pcpt)
{
int i;
Point pt;
/* 縦方向の位置を算出 */
pt.p.y = (mp->fontSize * 2 + CELLMG * 2) * pcpt->y;
/* 横方向の位置を算出 */
pt.p.x = 0;
for (i = 0; i < pcpt->x; i++)
pt.p.x += (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
/* 表示開始座標を加算 */
pt.p.x += mp->pos.p.x + mp->offset.p.x;
pt.p.y += mp->pos.p.y + mp->offset.p.y;
return pt.x_y;
}
/******************************************************************************
* focusOn(): 編集領域を設定
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* CPoint *pcpt セルの位置へのポインタ
*/
void focusOn(Mtx *mp, CPoint *pcpt)
{
Rect rc;
CAtt *pcatt;
char str[256], *ar;
pcatt = mp->cAttH + pcpt->x;
if (mp->focus == 2 || pcatt->attrib > 1)
/* すでに編集状態/数値、文字以外の属性 */
return;
mp->eCell = *pcpt;
if (mp->focus == 0) {
mp->focus++;
/* 選択状態の1段階 */
return;
}
mp->focus = 2;
/* 選択状態の第2段階 */
/* 編集セルのレクタングルを求める */
rc.l.l_t = 0;
rc.d.right = pcatt->length * mp->fontSize + CELLMG * 2;
rc.d.bottom = mp->fontSize * 2 + CELLMG * 2;
GMSlideRect(&rc, cptToLpt(mp, pcpt));
(*mp->tEdit)->lenMax = pcatt->length - 1; /* 編集文字数を設定 */
GMInsetRect(&rc, LONGWORD(CELLMG, CELLMG));
/* セル内のデータを編集できるように変換 */
ar = *(mp->cData + pcatt->array);
switch (pcatt->attrib) {
case 0: /* 数値文字列を右揃えで出力 */
sprintf(str, "%*d\0", pcatt->length - 1, *((int *) ar + pcpt->y));
break;
case 1: /* 文字列を左揃えで出力 */
strcpy(str, (ar + pcpt->y * pcatt->size));
break;
}
TMSetText(mp->tEdit, str, (int) strlen(str));
TMSetRect(mp->tEdit, &rc, &rc);
TMShow(mp->tEdit);
TMSetSelect(mp->tEdit, 0, (*mp->tEdit)->length, 0);
TMCaret(mp->tEdit, 1);
mp->edit = FALSE;
}
/******************************************************************************
* focusOff(): 編集レベルを1つ下げる
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
*/
void focusOff(Mtx *mp)
{
int lastFC;
Rect rc;
CAtt *pcatt = mp->cAttH + mp->eCell.x;
if (mp->focus == 0)
/* 編集中のセルがない */
return;
if (mp->focus == 2) {
TMCaret(mp->tEdit, 0);
TMHide(mp->tEdit);
}
/* 編集セルのレクタングルを求める */
rc.l.l_t = 0;
rc.d.right = pcatt->length * mp->fontSize + CELLMG * 2;
rc.d.bottom = mp->fontSize * 2 + CELLMG * 2;
GMSlideRect(&rc, cptToLpt(mp, &mp->eCell));
lastFC = GMForeColor(G_WHITE);
GMFillRect(&rc);
drawCellOne(mp, &mp->eCell); /* セルの再描画 */
mp->focus--;
mp->edit = FALSE;
drawFocus(mp);
GMForeColor(lastFC);
}
/******************************************************************************
* drawFocus(): 編集領域の描画
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
*/
void drawFocus(Mtx *mp)
{
int lastBC, lastFC;
Rect rc, rc2;
CAtt *pcatt = mp->cAttH + mp->eCell.x;
if (mp->focus == 0)
/* 編集中のセルがない */
return;
/* 編集セルのレクタングルを求める */
rc.l.l_t = 0;
rc.d.right = pcatt->length * mp->fontSize + CELLMG * 2;
rc.d.bottom = mp->fontSize * 2 + CELLMG * 2;
GMSlideRect(&rc, cptToLpt(mp, &mp->eCell));
lastFC = GMForeColor(G_BLACK);
lastBC = GMBackColor(G_WHITE);
GMFrameRect(&rc);
rc2.l.l_t = LONGWORD(rc.d.left + 1, rc.d.top + 1);
rc2.l.r_b = LONGWORD(rc.d.right - 1, rc.d.bottom - 1);
GMFrameRect(&rc2);
if (mp->focus == 2) {
TMCaret(mp->tEdit, 0);
GMInsetRect(&rc, LONGWORD(CELLMG, CELLMG));
TMUpDate(mp->tEdit, &rc); /* テキストの文字列を描画する */
TMCaret(mp->tEdit, 1);
}
GMBackColor(lastBC);
GMForeColor(lastFC);
}
/******************************************************************************
* mountFocus(): 編集領域のデータを配列に登録
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
*/
void mountFocus(Mtx *mp)
{
int len;
char str[256];
/* 数値と文字列の配列を示すポインタを共用体にする */
union {
int *i;
char *c;
} ar;
CAtt *pcatt = mp->cAttH + mp->eCell.x;
if (mp->focus < 2)
/* 編集中でなければ */
return;
if (!mp->edit)
/* 編集されていなければ */
return;
/* ar = 配列のポインタ */
ar.c = *(mp->cData + pcatt->array);
switch (pcatt->attrib) {
case 0: /* 文字列を数値に変換して代入 */
len = TMGetText(mp->tEdit, str, pcatt->length);
str[len] = 0;
if (sscanf(str, "%d", ar.i + mp->eCell.y) < 1)
/* 数値に変換できなければ */
*(ar.i + mp->eCell.y) = 0;
totalCell(mp, mp->eCell.x); /* 合計を再計算 */
break;
case 1: /* 文字列を配列にコピー */
len = TMGetText(mp->tEdit, str, pcatt->length);
str[len] = 0;
strcpy(ar.c + mp->eCell.y * pcatt->size, str);
break;
}
/* 確定したセル番号を保存 */
mp->mCell = mp->eCell;
}
/******************************************************************************
* cellEvent(): イベント毎のセルの編集処理
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* TsEvent *ptsev タスクマンイベントレコードへのポインタ
* 戻り値: int stat = 0: 編集しなかった
* = 1: 編集した
* (マウスダウンイベントの場合ポインタが表の
* 中ならばbit1が"1"になる。)
* < 0: エラーコード
*/
int cellEvent(Mtx *mp, TsEvent *ptsev)
{
int lastAP, lastFC, lastBC, lastFK;
int stat = 0;
int keyCode; /* キーコード */
LPoint lpt;
CPoint cpt, dcpt;
/* アクセスページを0と1ページにする */
lastAP = GMAPage(G_PAGE0 | G_PAGE1);
lastFC = GMForeColor(G_BLACK);
lastBC = GMBackColor(G_WHITE);
lastFK = GMFontKind(G_ROM12);
lpt = GMGlobalToLocal(ptsev->ev.where.x_y);
cpt = mp->eCell;
/* イベント毎に処理を行う */
switch (ptsev->ts.what) {
case E_IDLE: /* アイドルイベント */
if (mp->focus == 2)
stat = TMEventW(mp->tEdit, ptsev);
break;
case E_KEYDOWN: /* キーダウンイベント */
if (mp->focus == 0)
/* 入力状態でない場合 */
break;
/* ファンクションアサインテーブルによりキーコードを変換する */
keyCode = TMKeyToAsk(mp->tEdit, ptsev);
if (keyCode == -2) { /* テーブルに登録されてないか? */
/* OPT.1キーが押されたか? */
if (ptsev->ev.how & KS_OPT1)
/* ショートカットキーの処理 */
mp->edit |= TMEventW(mp->tEdit, ptsev);
else {
switch (ptsev->ev.whom.key.ascii) {
case '\r': /* リターンキーかENTERキー */
if (mp->focus == 2) {
mountFocus(mp); /* 編集結果を配列に保存 */
if (mp->edit)
stat = 1;
focusOff(mp);
focusOff(mp);
/* 次のセルへ編集領域を移動 */
dcpt.x = 0;
dcpt.y = 1;
nextCell(mp, &cpt, &dcpt);
}
focusOn(mp, &cpt);
drawFocus(mp);
break;
case '\x1b': /* ESCキー */
/* 入力状態を解除 */
focusOff(mp);
break;
default: /* その他のキー */
/* セルの入力を開始 */
if (mp->focus == 1) {
focusOn(mp, &mp->eCell);
drawFocus(mp);
}
mp->edit |= TMEventW(mp->tEdit, ptsev);
mp->edit |= stat;
break;
}
}
} else if (mp->focus == 1) {
/* 変換されたキーコードの場合 */
dcpt.x = 0;
dcpt.y = 0;
switch (keyCode) {
case 0x04: /* K_RIGHT */
dcpt.x = 1;
goto cursor;
case 0x13: /* K_LEFT */
dcpt.x = -1;
goto cursor;
case 0x05: /* K_UP */
dcpt.y = -1;
goto cursor;
case 0x18: /* K_DOWN */
dcpt.y = 1;
cursor:
mountFocus(mp); /* 編集結果を配列に保存 */
if (mp->edit)
stat = 1;
focusOff(mp);
focusOff(mp);
/* 次のセルへ編集領域を移動 */
nextCell(mp, &cpt, &dcpt);
focusOn(mp, &cpt);
drawFocus(mp);
break;
default:
/* その他のキーの場合 */
focusOn(mp, &mp->eCell);
drawFocus(mp);
mp->edit |= TMEventW(mp->tEdit, ptsev);
mp->edit |= stat;
}
} else {
/* その他のキーの場合 */
mp->edit |= TMEventW(mp->tEdit, ptsev);
mp->edit |= stat;
}
break;
case E_MSLDOWN: /* マウスレフトダウンイベント */
if (!checkCpt(mp, lpt, &cpt)) {
/* ポインタがセルの範囲外 */
mountFocus(mp); /* 編集結果を配列に保存 */
if (mp->edit)
stat = 1;
focusOff(mp);
focusOff(mp);
break;
}
if (mp->eCell.x != cpt.x || mp->eCell.y != cpt.y || mp->focus == 0) {
/* 以前と違うセルが選択された場合 */
mountFocus(mp); /* 編集結果を配列に保存 */
if (mp->edit)
stat = 1;
focusOff(mp);
focusOff(mp);
/* 編集領域を移動 */
focusOn(mp, &cpt);
drawFocus(mp);
} else if (mp->focus == 2)
/* テキストのイベント処理 */
mp->edit |= TMEventW(mp->tEdit, ptsev);
else if (mp->focus == 1) {
/* 編集可能状態にする */
focusOn(mp, &cpt);
drawFocus(mp);
mp->edit |= TMEventW(mp->tEdit, ptsev);
}
stat |= 2;
break;
case E_MSRDOWN: /* マウスライトダウンイベント */
if (GMPtInRect(&mp->rcAll, lpt)) {
if (mp->focus == 2) {
mp->edit |= TMEventW(mp->tEdit, ptsev);
mp->edit |= stat;
}
stat |= 2;
}
break;
}
GMAPage(lastAP);
GMForeColor(lastFC);
GMBackColor(lastBC);
GMFontKind(lastFK);
return stat;
}
/******************************************************************************
* nextCell(): 編集領域の移動の処理
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* CPoint *pcpt 現在/移動後のセル位置へのポインタ
* CPoint *pdcpt セルの移動方向へのポインタ
* 戻り値: LPoint
*/
void nextCell(Mtx *mp, CPoint *pcpt, CPoint *pdcpt)
{
/* 移動後のセル位置を求める */
pcpt->x += pdcpt->x;
pcpt->y += pdcpt->y;
if (pcpt->x < 1)
/* 最左行の場合 */
pcpt->x = 1;
else if (pcpt->x >= mp->cWide)
/* 最右行の場合 */
pcpt->x = mp->cWide - 1;
if (pcpt->y < 0)
/* 最上行の場合 */
pcpt->y = 0;
else if (pcpt->y >= mp->cHeight)
/* 最下行ののセルの場合 */
pcpt->y = mp->cHeight - 1;
}
/******************************************************************************
* checkCpt(): 指定座標で示されるセル番号を求める
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* LPoint lpt ポインタ座標
* CPoint *pcpt セルの位置へのポインタ
* 戻り値: BOOLEAN = TRUE: 正常
* = FALSE: セルが範囲外
*/
BOOLEAN checkCpt(Mtx *mp, LPoint lpt, CPoint *pcpt)
{
int x, cx, cy;
Point pt;
if (!GMPtInRect(&mp->rcAll, lpt))
/* 外枠より外の場合 */
return FALSE;
pt.x_y = lpt;
pt.p.y -= mp->pos.p.y + mp->offset.p.y;
/* セル番号に変換 */
cy = pt.p.y / (mp->fontSize * 2 + CELLMG * 2);
if (pt.p.y < 0 || cy >= mp->cHeight)
/* セルが範囲外 */
return FALSE;
pt.p.x -= mp->pos.p.x + mp->offset.p.x;
if (pt.p.x < 0)
/* セルが範囲外 */
return FALSE;
x = 0;
for (cx = 0; cx < mp->cWide; cx++) {
/* ポインタの座標よりセルの座標が大きくなるまでループ */
x += (mp->cAttH + cx)->length * mp->fontSize + CELLMG * 2;
if (pt.p.x < x)
/* 該当セル発見 */
break;
}
if (cx >= mp->cWide)
return FALSE;
/* セル番号を返す */
pcpt->x = cx;
pcpt->y = cy;
return TRUE;
}
/******************************************************************************
* totalCell(): 指定セルの合計を求める
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
int cx セルのx方向の位置
* 戻り値: BOOLEAN = TRUE: 正常
* = FALSE: セルが範囲外/セルの属性が数値以外
*/
BOOLEAN totalCell(Mtx *mp, int cx)
{
int i, x, lastFC, sum;
char *ar;
Rect rc;
CPoint cpt;
CAtt *pcatt = mp->cAttH + cx;
if (cx >= mp->cWide || pcatt->attrib != 0)
/* セルが範囲外/セルの属性が数値以外 */
return FALSE;
/* ar = 配列のポインタ */
ar = *(mp->cData + pcatt->array);
sum = 0;
/* 合計を算出 */
for (i = 0; i < mp->cHeight; i++)
sum += *((int *) ar + i);
/* 合計を配列に保存 */
*((int *) ar + mp->cHeight) = sum;
/* 合計用入力欄を描画 */
lastFC = GMForeColor(G_BLACK);
rc.d.top = mp->pos.p.y + mp->offset.p.y + mp->cHeight * (mp->fontSize * 2 + CELLMG * 2) + 1;
rc.d.bottom = rc.d.top + (mp->fontSize * 2 + CELLMG * 2);
x = 0;
for (i = 0; i < cx; i++)
x += (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
rc.d.left = mp->pos.p.x + OUTFRM;
rc.d.right = rc.d.left + pcatt->length * mp->fontSize + CELLMG * 2;
GMSlideRect(&rc, x << 16);
/* セルのフレームを描画 */
drawCellFrame(&rc, pcatt->attrib, 0);
cpt.x = cx;
cpt.y = mp->cHeight;
drawCellStr(mp, &rc, &cpt);
GMForeColor(lastFC);
return TRUE;
}
/******************************************************************************
* caretCell(): セルのカーソルの表示
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
*/
void caretCell(Mtx *mp, int flag)
{
if (mp->focus == 2)
TMCaret(mp->tEdit, flag);
}
/******************************************************************************
* clearCell(): セルデータの消去
******************************************************************************
* 引数: Mtx *mp 表の構造体へのポインタ
* Window *winPtr ウィンドウポインタ
*/
void clearCell(Mtx *mp, Window *winPtr)
{
int cx, cy;
char *ar;
CAtt *pcatt;
/* データ領域をクリア */
for (cx = 0; cx < mp->cWide; cx++) {
for (cy = 0; cy < mp->cHeight; cy++) {
pcatt = mp->cAttH + cx;
/* ar = 配列のポインタ */
ar = *(mp->cData + pcatt->array);
if (pcatt->attrib == 0)
*((int *) ar + cy) = 0;
else if (pcatt->attrib == 1)
*(ar + cy * pcatt->size) = 0;
}
}
/* 表全体をアップデートリージョンに登録 */
addUpdate(winPtr, &mp->rcAll);
}